@page "/Admin/Login"
@using AdminBlazor.Infrastructure.Encrypt
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Http
@using System.Collections.Concurrent
@using System.Web
@layout LayoutEmpty

<div style="position: absolute; top: 0px; left: 0px; width: 100%; overflow: hidden; height: 100%; z-index: 99;">
    <div class="login-page">
        <div class="login-box">
            <div class="card card-outline card-light">
                <div class="card-header d-block">
                    <h5 class="mb-3 mt-3 text-center"><b>@admin.Tenant?.Title</b></h5>
                </div>
                <div class="card-body login-card-body">
                    <div class="input-group mb-3">
                        <div class="form-floating"><input onkeydown="if(event.code=='Enter'&&this.value.length>0)$('#loginPassword')[0].focus()" @bind="username" id="loginUser" type="text" class="form-control" placeholder=""><label for="loginUser" style="font-weight:300">用户名</label></div>
                        <div class="input-group-text"><span class="fa fa-user"></span></div>
                    </div>
                    <div class="input-group mb-3">
                        <div class="form-floating"> <input onkeydown="if(event.code=='Enter'&&this.value.length>0)$('#loginSubmit').click()" @bind="password" id="loginPassword" type="password" class="form-control" placeholder=""><label for="loginPassword" style="font-weight:300">密码</label></div>
                        <div class="input-group-text"><span class="fas fa-lock"></span></div>
                    </div>
                    <div class="row">
                        <div class="col-8 d-inline-flex align-items-center">
                            <div class="form-check"><input @bind="remember" class="form-check-input" type="checkbox" id="flexCheckDefault"><label class="form-check-label" for="flexCheckDefault">记住</label></div>
                        </div>
                        <div class="col-4">
                            <div class="d-grid gap-2"><button @onclick="Submit" id="loginSubmit" class="btn btn-primary">登陆</button></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<div style="position: absolute; top: 0px; left: 0px; width: 100%; overflow: hidden; height: 100%; z-index: 1; pointer-events: none;">
    <video src="https://gw.alipayobjects.com/v/huamei_gcee1x/afts/video/jXRBRK_VAwoAAAAAAAAAAAAAK4eUAQBr" autoplay="autoplay" muted="muted" loop crossorigin="anonymous" style="width: 100%; height: 100%; object-fit: cover;"></video>
</div>

@code {
    [CascadingParameter, Inject] AdminContext admin { get; set; }
    [Inject] IFreeSql fsql { get; set; }
    [Inject] Scheduler scheduler { get; set; }
    [Inject] WebClientService webClientService { get; set; }
    string username, password;
    bool remember = true;

    async Task PasswordOnKeydown(KeyboardEventArgs e)
    {
        System.Console.WriteLine(e.Code);
        if (e.Code == "Enter" && password?.Length > 0)
        {
            await Submit();
        }
    }

    async Task Submit()
    {
        if (username.IsNull() || password.IsNull())
        {
            await JS.Error("登陆失败！", "用户名或密码不能为空");
            return;
        }

        var ip = admin.HttpContext.Connection?.RemoteIpAddress?.ToString() ?? "";
        if (limit.TryGetValue(ip, out var count) && count >= 5)
        {
            await JS.Error("频率过高！", "请过一会再试...");
            return;
        }

        var clientInfo = await webClientService.GetClientInfo();
        var log = new UserLoginEntity
        {
            LoginTime = DateTime.Now,
            Username = username,
            Browser = clientInfo.Browser,
            City = clientInfo.City,
            Device = clientInfo.Device,
            Engine = clientInfo.Engine,
            Ip = clientInfo.Ip,
            Language = clientInfo.Language,
            OS = clientInfo.OS,
            UserAgent = clientInfo.UserAgent,
        };
        var user = await fsql.Select<UserEntity>().Where(a => a.Username == username).FirstAsync();
        if (user == null || user.Password != password)
        {
            limit.AddOrUpdate(ip, ++count, (_, __) => count);
            if (removeLimit.IsNull())
                scheduler.AddTempTask(TimeSpan.FromSeconds(60), () => {
                    removeLimit = null;
                    limit.TryRemove(ip, out var _);
                });

            log.Type = UserLoginEntity.LoginType.登陆失败;
            await fsql.Insert(log).ExecuteAffrowsAsync();
            await JS.Error("登陆失败！", "用户名或密码不正确");
            return;
        }
        await admin.SignIn(user, remember);
        log.Type = UserLoginEntity.LoginType.登陆成功;
        await fsql.Insert(log).ExecuteAffrowsAsync();

        var redirect = nav.GetQueryStringValue("Redirect");
        if (redirect.IsNull()) redirect = "/Admin/";
        admin.Redirect(redirect);
    }

    string removeLimit;
    static ConcurrentDictionary<string, int> limit = new();
    async protected override Task OnInitializedAsync()
    {
        await admin.Init();
    }
}